package net.slteam.base;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.data.domain.Page;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@JsonInclude(JsonInclude.Include.NON_NULL)
@SuppressWarnings("unused")
public class SLPage<T> {

    @Schema(description = "当前页码，1为 第1页")
    private int pageNum = 1;

    @Schema(description = "每页查询数量,默认10条记录")
    private int pageSize = 10;

    /* 如果超过19位数需要优化 */
    @Schema(description = "总数据")
    private int total = 0;

    @Schema(description = "页数")
    private int pages = 0;

    @Schema(description = "数据集合")
    private List<T> list;

    @Schema(description = "更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updated = new Date();

    public SLPage(Collection<T> list) {
        this.list = new ArrayList<>(list);
        this.total = list.size();

        this.pages = list.size() > 0 ? 1 : 0;
    }

    public SLPage(Collection<T> list,
                  IPage iPage) {
        this.list = new ArrayList<>(list);
        this.total = list.size();

        this.pageNum = iPage.getPageNum();
        this.pageSize = iPage.getPageSize();
    }

    public SLPage(Collection<T> list,
                  IPage iPage,
                  Integer total) {
        this.list = new ArrayList<>(list);
        this.total = total;

        this.pageNum = iPage.getPageNum();
        this.pageSize = iPage.getPageSize();
    }

    public SLPage(Page<T> page) {
        this.list = page.getContent();
        this.total = (int)page.getTotalElements();

        this.pageNum = page.getPageable().getPageNumber();
        this.pageSize = page.getPageable().getPageSize();

        this.pages = page.getTotalPages();
    }

    public SLPage() {
    }

    public static <T> SLPage<T> toSLPage(Page<IBaseBean> page,
                                         Class<T> tClass) {
        SLPage<T> slPage = new SLPage(page);
        slPage.setList(page.getContent().stream().map(a -> a.toDTO(tClass)).collect(Collectors.toList()));
        return slPage;
    }

    public static <T> SLPage<T> directFromGithubPage(PageInfo<T> githubPage) {
        SLPage<T> slPage = new SLPage<>();
        slPage.setPageNum(githubPage.getPageNum());
        slPage.setPageSize(githubPage.getPageSize());
        slPage.setTotal((int)githubPage.getTotal());
        slPage.setList(githubPage.getList());
        slPage.setPages(githubPage.getPages());
        return slPage;
    }

    /**
     * Bean 进行转换为对应的DTO
     *
     * @param tClass
     * @return
     */
    public void convertToDTOList(Class<T> tClass) {

        if (CollectionUtils.isEmpty(this.list)) {
            return;
        }

        Assert.isInstanceOf(tClass, this.list.get(0), "该类型不可以进行DTO转换");
        this.list = this.list.stream().map(a -> ((BaseBean) a).toDTO(tClass)).collect(Collectors.toList());
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public Date getUpdated() {
        return updated;
    }

    public void setUpdated(Date updated) {
        this.updated = updated;
    }

    @Override
    public String toString() {
        return "SLPage{" +
                "pageNum=" + pageNum +
                ", pageSize=" + pageSize +
                ", total=" + total +
                ", pages=" + pages +
                ", list=" + list +
                ", updated=" + updated +
                '}';
    }
}
